package com.hx.thread.deadlock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

/**
 * @author Minghua Chen
 * @date 2020-09-06 16:28
 */
public class DetectDeadLock implements Runnable {
    private static final Logger logger = LoggerFactory.getLogger(DetectDeadLock.class);

    private int flag;
    static final Object object1 = new Object();
    static final Object object2 = new Object();

    @Override
    public void run() {
        logger.info("flag为" + flag);
        if (flag == 1) {
            synchronized (object1) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (object2) {
                    logger.info("当前线程获得两把锁");
                }
            }
        }
        if (flag == 2) {
            synchronized (object2) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (object1) {
                    logger.info("当前线程获得两把锁");
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        DetectDeadLock task1 = new DetectDeadLock();
        DetectDeadLock task2 = new DetectDeadLock();
        task1.flag = 1;
        task2.flag = 2;
        new Thread(task1, "t1").start();
        new Thread(task2, "t2").start();
        Thread.sleep(1000);
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        long[] deadlockedThreads = threadMXBean.findDeadlockedThreads();
        if (deadlockedThreads != null && deadlockedThreads.length > 0) {
            for (long deadlockedThread : deadlockedThreads) {
                ThreadInfo threadInfo = threadMXBean.getThreadInfo(deadlockedThread);
                logger.info("线程id为: " + threadInfo.getThreadId() + ",线程名为: " + threadInfo.getThreadName() + "的线程发送死锁,需要的锁正被" + threadInfo.getLockOwnerName() + "持有");
            }
        }
    }
}
